package org.longteng.sys;

import lombok.extern.slf4j.Slf4j;
import org.longteng.core.utils.StringExUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * 取得本机信息工具类
 * <br>本机IP,取MAC地址,获取客户端IP
 * @author hymn.com
 */
@Slf4j
public class ComputerInfoUtil {

    /**
     * 返回本机IP
     * @return
     */
    public static String getIpAddr() {
        InetAddress ia = null;
        String localip = "";

        try {
            ia = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            log.error("取机器主机失败", e);
        }
        localip = ia.getHostAddress();
        log.debug("取机器主机IP,本机名称是：{},本机的ip:{}", ia.getHostName(), localip);
        return  localip;
    }

    /**
     *获取MAC地址的方法
     * @return
     */
    public static String getMACAddress() {
        InetAddress ia = null;

        try {
            ia = InetAddress.getLocalHost();
            return getMACAddress(ia);
        } catch (UnknownHostException e) {
            log.error("取机器主机失败", e);
        } catch (SocketException e) {
            log.error("取机器主机网上失败", e);
        }
        return null;
    }

    /**
     *获取MAC地址的方法
     * @return
     */
    private static String getMACAddress(InetAddress ia) throws SocketException {
        // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
        byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
        // 下面代码是把mac地址拼装成String
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        // 把字符串所有小写字母改为大写成为正规的mac地址并返回
        return sb.toString().toUpperCase();
    }

    /**
     * 获取客户端IP地址
     *
     * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，X-Forwarded-For中第一个非unknown的有效IP字符串，则为真实IP地址
     */
    public static String getRemoteIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringExUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringExUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringExUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringExUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringExUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            log.error("获取客户端IP地址异常。", e);
        }

        if (log.isDebugEnabled()) {
            log.debug("获取客户端IP地址:{},对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割.", ip);
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if(!StringExUtils.isEmpty(ip) && ip.length() > 15) {
            if(ip.indexOf(',') > 0) {
                ip = ip.substring(0, ip.indexOf(','));
            }
        }

        return ip;
    }

    /**
     * 是否手机端的请求
     * @param request
     * @return
     */
    public static boolean clientIsMoblie(HttpServletRequest request) {
        boolean isMoblie = false;
        String[] mobileAgents = { "iphone", "android","ipad", "phone", "mobile", "wap", "netfront", "java", "opera mobi",
                "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod",
                "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma",
                "docomo", "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos",
                "techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem",
                "wellcom", "bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos",
                "pantech", "gionee", "portalmmm", "jig browser", "hiptop", "benq", "haier", "^lct", "320x320",
                "240x320", "176x220", "w3c ", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac",
                "blaz", "brew", "cell", "cldc", "cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs",
                "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi",
                "mot-", "moto", "mwbp", "nec-", "newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port",
                "prox", "qwap", "sage", "sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem",
                "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v",
                "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc", "winw", "winw", "xda", "xda-",
                "Googlebot-Mobile" };
        String agent=request.getHeader("User-Agent");
        if(log.isDebugEnabled()) {
            log.debug("是否手机端的请求User-Agent:{}",agent);
        }
        if (agent != null) {
            for (String mobileAgent : mobileAgents) {
                if (agent.toLowerCase().indexOf(mobileAgent) >= 0
                        && agent.toLowerCase().indexOf("windows nt")<=0 && agent.toLowerCase().indexOf("macintosh")<=0) {
                    isMoblie = true;
                    break;
                }
            }
        }
        return isMoblie;
    }

    /**
     * 返回前端cookie信息
     * @param request
     * @param cookieKey
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieKey) {
        String cookieValue = null;
        Cookie[] cookies = request.getCookies();
        if(cookies!=null&&cookies.length!=0) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(cookieKey)) {
                    cookieValue = cookie.getValue();
                    break;
                }
            }
        }
        return cookieValue;
    }
}
